package monitormercado.negocio.analise.indicador.williamsr;

import java.util.Date;
import java.util.List;

import monitormercado.negocio.Tick.ComparadorTick;
import monitormercado.negocio.Tick.Tick;
import monitormercado.negocio.analise.indicador.Indicador;
import monitormercado.util.Util;

/**
 * 
 * Williams %R
 * 
 * http://en.wikipedia.org/wiki/Williams_%25R
 * 
 * Williams %R, or just %R, is a technical analysis oscillator showing the
 * current closing price in relation to the high and low of the past N days (for
 * a given N). It was developed by trader and author Larry Williams and is
 * normally used just in the stock market.
 * 
 * %R = ((closeToday - highNdays) / (highNdays - lowNdays)) * 100
 * 
 * The oscillator is on a negative scale, from -100 (lowest) up to 0 (highest).
 * Such a scale is a little unusual and is sometimes found altered (by adding
 * 100), but needn't cause any confusion. A value of -100 is the close today at
 * the lowest low of the past N days, and 0 is a close today at the highest high
 * of the past N days.
 * 
 * Williams used a 10 trading day period and considered values below -80 as
 * oversold and above -20 as overbought. But they were not to be traded
 * directly, instead his rule to buy an oversold was: %R reaches -100%; Five
 * trading days pass since -100% was last reached; %R rises above -95% or -85%.
 * 
 * or conversely to sell an overbought condition: %R reaches 0%; Five trading
 * days pass since 0% was last reached; %R falls below -5% or -15%.
 * 
 * The timeframe can be changed for either more sensitive or smoother results.
 * The more sensitive you make it, though, the more false signals you will get.
 * The "close-position within a range" in the %R indicator is the same as the %K
 * stochastic oscillator, on a different scale.
 * 
 * 
 */
public class WilliamsR extends Indicador {

	private double valor;
	private int periodo;

	public double getValor() {
		return valor;
	}

	public void setValor(double valor) {
		this.valor = valor;
	}

	public int getPeriodo() {
		return periodo;
	}

	public void setPeriodo(int periodo) {
		this.periodo = periodo;
	}

	public static double calcular(double fechamentoAtual, double maximoDoPeriodo, double minimoDoPeriodo) {
		return 100 * ((fechamentoAtual - maximoDoPeriodo) / (maximoDoPeriodo - minimoDoPeriodo));
	}

	public static double calcular(List<Tick> ticks) {
		
		double fechamentoAtual = Util.getUltimoTick(ticks, ComparadorTick.data).getFechamento();
		double maximoDoPeriodo = Util.getUltimoTick(ticks, ComparadorTick.maximo).getMaximo();
		double minimoDoPeriodo = Util.getPrimeiroTick(ticks,ComparadorTick.minimo).getMinimo();
		return calcular(fechamentoAtual, maximoDoPeriodo, minimoDoPeriodo);
	}

	public WilliamsR(Date data, String siglaAcao, int periodicidade, double fechamentoAtual,
			double maximoDoPeriodo, double minimoDoPeriodo, int periodo) {
		super(data, siglaAcao, periodicidade);
		this.periodo = periodo;
		this.valor = calcular(fechamentoAtual, maximoDoPeriodo, minimoDoPeriodo);
	}

	public WilliamsR(List<Tick> ticks, int periodicidade) {
		super(Util.getUltimoTick(ticks, ComparadorTick.data).getData(), ticks
				.get(ticks.size() - 1).getSigla(), periodicidade);
		this.periodo = ticks.size();
		this.valor = calcular(ticks);
	}
	
	public String toString() {
		return "WILLIAMSR" + " | data: " + this.getData() + " | siglaAcao: " + this.getSiglaAcao() + " | periodicidade: "
				+ this.getPeriodicidade() + " | periodo: " + this.getPeriodo() + " | valor: "
				+ this.getValor();
	}

}
